home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / windows / static / static.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-29  |  26.4 KB  |  660 lines

  1. #define APPNAME "StaticApp"
  2. // NOTE: We couldn't use "STATIC" here, because that is already the name
  3. // of a type of window in the system, and it would cause problems if we
  4. // re-defined this.
  5.  
  6. /*
  7.  *    Static.C
  8.  *
  9.  *    (C) Copyright Microsoft Corp. 1993.  All rights reserved.
  10.  *
  11.  *    You have a royalty-free right to use, modify, reproduce and 
  12.  *    distribute the Sample Files (and/or any modified version) in 
  13.  *    any way you find useful, provided that you agree that 
  14.  *    Microsoft has no warranty obligations or liability for any 
  15.  *    Sample Application Files which are modified. 
  16.  */
  17.  
  18. #include <windows.h>    // Defines bulk of Windows functions and such...
  19. #include <mmsystem.h>    // Defines additional Multi-Media functions...
  20.  
  21. #if !defined(WIN32)
  22.     #include <wing.h>    // Defines WinG functions. Not use on Win32
  23. #endif
  24.  
  25. #include <stdlib.h>        // Since I am using 'rand()'
  26.  
  27. #include "static.h"        // Local header
  28.  
  29. //  ==========================================================================
  30. //  GLOBAL VARIABLES ---------------------------------------------------------
  31. //  ==========================================================================
  32.  
  33. char    szAppName[]= APPNAME;    // A handy string to identify this app
  34. char    szTitle[] = APPNAME ": Sample App"; // For the title bar
  35.  
  36. HINSTANCE hInstApp;        // A handle that identifies this 'process'
  37. HWND      hwndApp;        // A handle that identifies the main window
  38. HPALETTE  hpalApp;        // A handle that identifies the main palette
  39. BOOL      fAppActive;    // A boolean that refers to this app being 'foreground'
  40.  
  41. // Define a structure that we will be using for keeping information about the
  42. // image we are currently drawing into.
  43. typedef struct _IMAGE {
  44.     BITMAPINFOHEADER bi;  // Bitmap header information.
  45.     RGBQUAD aColors[256]; // Palette color table
  46.     union { // Now for the pointer to the data buffer we can whack on:
  47.         LPVOID  lpvData; // This is the type that WinG likes to deal with
  48.         LPBYTE  lpIndex; // This is just to make it easier for us to access it
  49.     };
  50. } _IMAGE;
  51. _IMAGE image; // Contains most necessary information about the image to display
  52.  
  53.  
  54. // Define a structure for holding our palette data. This is the color palette
  55. // that will be assigned to both the above image, and be selected into the
  56. // 'Device Context' for the screen so we will have an 'Identity' palette which
  57. // will make for much faster screen updating.
  58. typedef struct _PALETTE
  59. {
  60.     WORD Version;
  61.     WORD NumberOfEntries;
  62.     PALETTEENTRY aEntries[256];
  63. } _PALETTE;
  64. _PALETTE LogicalPalette = {0x300, 256}; // The 'logical' palette we will use
  65.     // "0x300" = Windows 3.0 or later
  66.     // "256" = Number of colors
  67.  
  68. long Orientation = 1; // Bitmap Orientation: TopDown=1, BottomUp=-1
  69. HDC hdcImage = NULL;  // A handle to the Device Context for our image
  70.  
  71. HBITMAP gbmOldMonoBitmap = 0;    // Storage for the 'original' bitmap from our
  72.                                 // Device Context, we need to restore it
  73.                                 // later on, so we need to save it here.
  74.  
  75.  
  76. //  ==========================================================================
  77. //  FUNCTION DEFINITIONS -----------------------------------------------------
  78. //  ==========================================================================
  79.  
  80. // Forward declarations for all functions.
  81. // Listed in order they appear in this source listing
  82.  
  83. BOOL AppInit(HINSTANCE hInst,HINSTANCE hPrev,int sw,LPSTR szCmdLine);
  84. BOOL AppIdle(void);
  85. LONG FAR PASCAL AppWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
  86. BOOL AppPaint (HWND hwnd, HDC hdc);
  87. LONG AppCommand (HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
  88. BOOL FAR PASCAL AppAbout(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
  89. void AppExit(void);
  90.  
  91.  
  92. /*----------------------------------------------------------------------------*\
  93. |   WinMain( hInst, hPrev, lpszCmdLine, cmdShow )                              |
  94. |                                                                              |
  95. |   Description:                                                               |
  96. |       The main procedure for the App.  After initializing, it just goes      |
  97. |       into a message-processing loop until it gets a WM_QUIT message         |
  98. |       (meaning the app was closed).                                          |
  99. |                                                                              |
  100. |   Arguments:                                                                 |
  101. |       hInst           instance handle of this instance of the app            |
  102. |       hPrev           instance handle of previous instance, NULL if first    |
  103. |       szCmdLine       ->null-terminated command line                         |
  104. |       cmdShow         specifies how the window is initially displayed        |
  105. |                                                                              |
  106. |   Returns:                                                                   |
  107. |       The exit code as specified in the WM_QUIT message.                     |
  108. |                                                                              |
  109. \*----------------------------------------------------------------------------*/
  110. int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
  111. {
  112.     MSG     msg;
  113.  
  114.     // NOTE: On Win32, hPrev will -always- be NULL
  115.  
  116.     // Do application initialization stuff
  117.     if (!AppInit(hInst,hPrev,sw,szCmdLine)) {
  118.         return 0; // Something failed to initialize
  119.     }
  120.     
  121.     // Poll for messages from event queue.
  122.     // loop continues until WM_QUIT is encountered    
  123.     for (;;) {
  124.         if (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE)) {
  125.             if (msg.message == WM_QUIT) {
  126.                 // When WM_QUIT comes through, we're DONE!
  127.                 break;
  128.             }
  129.             TranslateMessage(&msg); // Does some very necessary stuff
  130.             DispatchMessage(&msg);  // Does some very necessary stuff
  131.         } else {
  132.             if (AppIdle()) {
  133.                 WaitMessage();    // Defer to all other apps until a message
  134.                                 // gets put into our message queue
  135.             }
  136.         }
  137.     }
  138.     
  139.     AppExit();    // Do application exiting stuff
  140.  
  141.     return msg.wParam;
  142. }
  143.  
  144. /*----------------------------------------------------------------------------*\
  145. |   AppInit( hInst, hPrev)                                                     |
  146. |                                                                              |
  147. |   Description:                                                               |
  148. |       This is called when the application is first loaded into               |
  149. |       memory.  It performs all initialization that doesn't need to be done   |
  150. |       once per instance.                                                     |
  151. |                                                                              |
  152. |   Arguments:                                                                 |
  153. |       hInstance       instance handle of current instance                    |
  154. |       hPrev           instance handle of previous instance                   |
  155. |                                                                              |
  156. |   Returns:                                                                   |
  157. |       TRUE if successful, FALSE if not                                       |
  158. |                                                                              |
  159. \*----------------------------------------------------------------------------*/
  160. BOOL AppInit(HINSTANCE hInst,HINSTANCE hPrev,int sw,LPSTR szCmdLine)
  161. {
  162.     WNDCLASS cls;
  163.  
  164.     // Save instance handle for DialogBoxs as a global variable
  165.     hInstApp = hInst;
  166.  
  167.     if (!hPrev) {
  168.         // We don't already have a version running, so we need to
  169.         // register our window class with the system
  170.         cls.hCursor        = LoadCursor(NULL,IDC_ARROW);
  171.         cls.hIcon          = LoadIcon(hInst,szAppName);
  172.         cls.lpszMenuName   = szAppName;
  173.         cls.lpszClassName  = szAppName;
  174.         cls.hbrBackground  = (HBRUSH)(COLOR_WINDOW + 1);
  175.         cls.hInstance      = hInst;
  176.         cls.style          = CS_BYTEALIGNCLIENT | CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
  177.         cls.lpfnWndProc    = (WNDPROC)AppWndProc;
  178.         cls.cbWndExtra     = 0;
  179.         cls.cbClsExtra     = 0;
  180.  
  181.         if (!RegisterClass(&cls)) {
  182.             return FALSE; // Failed to register class. No need to continue.
  183.         }
  184.     }
  185.  
  186.     hwndApp = CreateWindow (szAppName,  // Class name
  187.                 szTitle,                // Caption
  188.                 WS_OVERLAPPEDWINDOW,    // Style bits
  189.                 CW_USEDEFAULT, 0,       // Position (x,y)
  190.                 320, 200,               // Size (w,h)
  191.                 (HWND)NULL,             // Parent window (no parent)
  192.                 (HMENU)NULL,            // use class menu
  193.                 hInst,                  // handle to current process instance
  194.                 (LPSTR)NULL             // no params to pass on
  195.                );
  196.  
  197.     if (hwndApp) {
  198.         ShowWindow(hwndApp,sw); // Time to display the window.
  199.         return TRUE;
  200.     } else {
  201.         return FALSE; // Failed to create window. No need to continue
  202.     }
  203.  
  204. }
  205.  
  206. /*----------------------------------------------------------------------------*\
  207. |   AppIdle()                                                                  |
  208. |                                                                              |
  209. |   Description:                                                               |
  210. |       place to do idle time stuff.                                           |
  211. |                                                                              |
  212. |   Returns:                                                                   |
  213. |       RETURN TRUE IF YOU HAVE NOTHING TO DO OTHERWISE YOUR APP WILL BE A     |
  214. |       CPU PIG!                                                               |
  215. \*----------------------------------------------------------------------------*/
  216. BOOL AppIdle()
  217. {
  218.     if (fAppActive) { // we are running in the foreground
  219.         return TRUE;        // We currently aren't doing anything at idle time
  220.     } else { // we are running in the background
  221.         return TRUE;        // We currently aren't doing anything at idle time
  222.     }
  223.  
  224.     // You will want to return FALSE here if any processing was done in this
  225.     // function that might have caused some windows messages, or will require
  226.     // the window to be repainted. If all you do is calculate and store
  227.     // some values to be used later, you can return TRUE.
  228. }
  229.  
  230.  
  231. /*----------------------------------------------------------------------------*\
  232. |   AppWndProc( hwnd, uiMessage, wParam, lParam )                              |
  233. |                                                                              |
  234. |   Description:                                                               |
  235. |       The window proc for the app's main (tiled) window.  This processes all |
  236. |       of the parent window's messages.                                       |
  237. |                                                                              |
  238. \*----------------------------------------------------------------------------*/
  239. LONG FAR PASCAL AppWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
  240. {
  241.     static int XOffset, YOffset;
  242.     static int dxClient, dyClient; // The 'Client' size. (drawing area of window)
  243.     
  244.     PAINTSTRUCT ps;
  245.     HDC hdc;
  246.     UINT uMappedColors;
  247.     
  248.     switch (msg) {
  249.         case WM_CREATE:
  250.             // This occures during 'CreateWindow' time. Here is where we can
  251.             // easily initialize some things for this window.
  252.             srand ((int)GetTickCount()); // initialize the random seed
  253.             SetTimer(hwnd, 1, 1, NULL);  // start up the WM_TIMER messages
  254.                                          // We will force a recalc/redraw of
  255.                                          // our main window on each WM_TIMER
  256.         break;
  257.         
  258.         case WM_TIMER:
  259.             // This comes to us because we called 'SetTimer(...)'.
  260.             InvalidateRect (hwnd, NULL, FALSE); // Just force a redraw
  261.             break;
  262.  
  263.         case WM_ACTIVATEAPP:
  264.             // The application z-ordering has changed. If we are now the
  265.             // foreground application wParm will be TRUE.
  266.             fAppActive = (BOOL)wParam;
  267.             break;
  268.  
  269.         case WM_ERASEBKGND:
  270.             return TRUE;
  271.             break;
  272.  
  273.         case WM_SIZE:
  274.             // This message comes to us because the window size has been
  275.             // changed. It also comes to us when the application is first
  276.             // being executed.
  277.             dxClient = LOWORD(lParam); // The 'new' width of our window
  278.             dyClient = HIWORD(lParam); // The 'new' height of our window
  279.  
  280.             if(hdcImage)     {
  281.                 // Our image Device Context has already been created, so
  282.                 // we can just use it. But we need to create a new bitmap
  283.                 // to draw into. We also need to make sure we delete the
  284.                 // previous bitmap -afterwards-.
  285.                 HBITMAP hbm;
  286.  
  287.                 //  Create a new 8-bit WinGBitmap with the new size
  288.                 image.bi.biWidth = dxClient;
  289.                 image.bi.biHeight = dyClient * Orientation;
  290. #if defined(WIN32)
  291.                 hbm = CreateDIBSection (hdcImage, (BITMAPINFO far *)&image.bi,
  292.                     DIB_PAL_COLORS, &image.lpvData, NULL, 0);
  293. #else
  294.                 hbm = WinGCreateBitmap(hdcImage, (BITMAPINFO far *)&image.bi,
  295.                     &image.lpvData);
  296. #endif
  297.                 if (!hbm) {
  298.                     //MessageBox (GetFocus(), "Failed to create Bitmap", szAppName, 0);
  299.                 } else {
  300.                     // Make sure that 'biSizeImage' reflects the
  301.                     // size of the bitmap data.
  302.                     image.bi.biSizeImage = (image.bi.biWidth * image.bi.biHeight);
  303.                     image.bi.biSizeImage *= Orientation;
  304.                     //  Select it in and delete the old one
  305.                     hbm = (HBITMAP)SelectObject(hdcImage, hbm);
  306.                     DeleteObject(hbm); // Make sure you delete the previous one!
  307.                 }
  308.             } else {
  309.                 //  Create a new WinGDC and 8-bit WinGBitmap
  310.  
  311.                 HBITMAP hbm;
  312.                 int Counter;
  313.                 HDC Screen;
  314.                 //RGBQUAD far *pColorTable;
  315.  
  316.                 //  Get WinG to recommend the fastest DIB format
  317. #if defined(WIN32)
  318.                 if (FALSE) {
  319. #else
  320.                 if(WinGRecommendDIBFormat((BITMAPINFO far *)&image.bi))    {
  321. #endif
  322.                     //  make sure it's 8bpp and remember the orientation
  323.                     image.bi.biBitCount = 8;
  324.                     image.bi.biCompression = BI_RGB;
  325.                     Orientation = image.bi.biHeight;
  326.                 } else {
  327.                     //  set it up ourselves
  328.                     image.bi.biSize = sizeof(BITMAPINFOHEADER);
  329.                     image.bi.biPlanes = 1;
  330.                     image.bi.biBitCount = 8;
  331.                     image.bi.biCompression = BI_RGB;
  332.                     image.bi.biSizeImage = 0;
  333.                     image.bi.biClrUsed = 0;
  334.                     image.bi.biClrImportant = 0;
  335.                 }
  336.  
  337.                 image.bi.biWidth = LOWORD(lParam);
  338.                 image.bi.biHeight = HIWORD(lParam) * Orientation;
  339.  
  340.                 //  create an identity palette from the DIB's color table
  341.  
  342.                 // Get the Device Context of the screen
  343.                 Screen = GetDC(HWND_DESKTOP);
  344.  
  345.                 // Get the 20 system colors as PALETTEENTRIES
  346.                 GetSystemPaletteEntries(Screen,0,10,LogicalPalette.aEntries);
  347.                 GetSystemPaletteEntries(Screen,246,10,LogicalPalette.aEntries + 246);
  348.                 
  349.                 // Only a few DCs available, free this up so we aren't a hog
  350.                 ReleaseDC(0,Screen);
  351.  
  352.                 // Initialize the logical palette and DIB color table
  353.                 // Note that we are doing this as double entries. Making
  354.                 // sure that we keep both tables -identical- this is to
  355.                 // make sure that we can end up with an 'identity palette'
  356.                 // which means that both the colortable assigned to the DIB
  357.                 // and the palette entries associated with the palette
  358.                 // that is selected into the Device Context are identical.
  359.  
  360.                 for(Counter = 0; Counter < 10; Counter++) {
  361.                 // copy the system colors into the DIB header
  362.                 // WinG will do this in WinGRecommendDIBFormat,
  363.                 // but it may have failed above so do it here anyway
  364.  
  365.                     // The low end colors...                
  366.                     image.aColors[Counter].rgbRed =
  367.                         LogicalPalette.aEntries[Counter].peRed;
  368.                     image.aColors[Counter].rgbGreen =
  369.                         LogicalPalette.aEntries[Counter].peGreen;
  370.                     image.aColors[Counter].rgbBlue =
  371.                         LogicalPalette.aEntries[Counter].peBlue;
  372.                     image.aColors[Counter].rgbReserved = 0;
  373.                     LogicalPalette.aEntries[Counter].peFlags = 0;
  374.                                             
  375.                     // And the high end colors...
  376.                     image.aColors[Counter + 246].rgbRed =
  377.                         LogicalPalette.aEntries[Counter + 246].peRed;
  378.                     image.aColors[Counter + 246].rgbGreen =
  379.                         LogicalPalette.aEntries[Counter + 246].peGreen;
  380.                     image.aColors[Counter + 246].rgbBlue =
  381.                         LogicalPalette.aEntries[Counter + 246].peBlue;
  382.                     image.aColors[Counter + 246].rgbReserved = 0;
  383.                     LogicalPalette.aEntries[Counter + 246].peFlags = 0;
  384.                 }
  385.  
  386.                 // Now fill in all of the colors in the middle to reflect
  387.                 // the colors that we are wanting. Here, we are just
  388.                 // setting random values.
  389.                 for(Counter = 10;Counter < 246;Counter++) {
  390.                     image.aColors[Counter].rgbRed =
  391.                         LogicalPalette.aEntries[Counter].peRed = rand()%255;
  392.                     image.aColors[Counter].rgbGreen =
  393.                         LogicalPalette.aEntries[Counter].peGreen = rand()%255;
  394.                     image.aColors[Counter].rgbBlue =
  395.                         LogicalPalette.aEntries[Counter].peBlue = rand()%255;
  396.                     image.aColors[Counter].rgbReserved = 0;
  397.                     // In order for this to be an identity palette, it is
  398.                     // important that we not only get this color, but that
  399.                     // we get it in THIS location. Using PC_NOCOLLAPSE tells
  400.                     // the system not to 'collapse' this entry to another
  401.                     // palette entry that already has this color.
  402.                     LogicalPalette.aEntries[Counter].peFlags = PC_NOCOLLAPSE;
  403.                 }
  404.  
  405.                 // The logical palette table is fully initialized.
  406.                 // All we have to do now, is create it.
  407.                 hpalApp = CreatePalette((LOGPALETTE far *)&LogicalPalette);
  408.                 
  409.                 //  Create a WinGDC and Bitmap, then select away
  410. #if defined (WIN32)
  411.                 hdcImage = CreateCompatibleDC (NULL); // Create a DC compatible with current screen
  412. #else
  413.                 hdcImage = WinGCreateDC();
  414. #endif
  415.                 image.bi.biWidth = LOWORD(lParam);
  416.                 image.bi.biHeight = HIWORD(lParam) * Orientation;
  417.  
  418. #if defined (WIN32)
  419.                 hbm = CreateDIBSection (hdcImage, (BITMAPINFO far *)&image.bi, DIB_PAL_COLORS, &image.lpvData, NULL, 0);
  420. #else
  421.                 hbm = WinGCreateBitmap(hdcImage,(BITMAPINFO far *)&image.bi, &image.lpvData);
  422. #endif
  423.                 // Make sure that 'biSizeImage' reflects the
  424.                 // size of the bitmap data.
  425.                 image.bi.biSizeImage = (image.bi.biWidth * image.bi.biHeight);
  426.                 image.bi.biSizeImage *= Orientation;
  427.                 //  Store the old hbitmap to select back in before deleting
  428.                 gbmOldMonoBitmap = (HBITMAP)SelectObject(hdcImage, hbm);
  429.             }
  430.  
  431.             PatBlt(hdcImage, 0,0,dxClient,dyClient, BLACKNESS);
  432.         break;
  433.  
  434.     case WM_COMMAND:
  435.         return AppCommand(hwnd, msg, wParam, lParam);
  436.  
  437.     case WM_PALETTECHANGED:
  438.         if ((HWND)wParam == hwnd) {
  439.             break;
  440.         }
  441.  
  442.         // fall through to WM_QUERYNEWPALETTE
  443.  
  444.     case WM_QUERYNEWPALETTE:
  445.         hdc = GetDC(hwnd);
  446.  
  447.         if (hpalApp) {
  448.             SelectPalette(hdc, hpalApp, FALSE);
  449.         }
  450.  
  451.         uMappedColors = RealizePalette(hdc);
  452.         ReleaseDC(hwnd,hdc);
  453.  
  454.         if (uMappedColors>0) {
  455.             InvalidateRect(hwnd,NULL,TRUE);
  456.             return TRUE;
  457.         } else {
  458.             return FALSE;
  459.         }
  460.         break;
  461.  
  462.  
  463.     case WM_PAINT:
  464.         hdc = BeginPaint(hwnd,&ps);
  465.         SelectPalette(hdc, hpalApp, FALSE);
  466.         RealizePalette(hdc);
  467.         AppPaint (hwnd,hdc);
  468.         EndPaint(hwnd,&ps);
  469.         return 0L;
  470.     
  471.     case WM_DESTROY:
  472.         PostQuitMessage(0);
  473.         break;
  474.     }
  475.     
  476.     return DefWindowProc(hwnd,msg,wParam,lParam);
  477. }
  478.  
  479.  
  480. /*----------------------------------------------------------------------------*\
  481. |   AppPaint(hwnd, hdc)                                                        |
  482. |                                                                              |
  483. |   Description:                                                               |
  484. |       The paint function.  Right now this does nothing.                      |
  485. |                                                                              |
  486. |   Arguments:                                                                 |
  487. |       hwnd             window painting into                                  |
  488. |       hdc              display context to paint to                           |
  489. |                                                                              |
  490. |   Returns:                                                                   |
  491. |       nothing                                                                |
  492. |                                                                              |
  493. \*----------------------------------------------------------------------------*/
  494. BOOL AppPaint (HWND hwnd, HDC hdc)
  495. {
  496.     DWORD l;
  497.     RECT rc;
  498.     unsigned char ch=0;
  499. #if defined (WIN32)
  500.     BYTE *lpData;
  501. #else
  502.     BYTE __huge *lpData;
  503. #endif
  504.  
  505.     // The data in our bitmap image is in 8bit chunks. Each element is an
  506.     // index value to the colortable that is associated with the bitmap,
  507.     // which, since we took pains to create an 'identity palette', is also
  508.     // the same as the palette currently selected into this device context.
  509.  
  510.     if (image.lpIndex) {
  511.         lpData = image.lpIndex;
  512.         ch = rand()%256;
  513.         for (l=0; l<image.bi.biSizeImage; l++) {
  514.             // Now's the time to draw in some random static.
  515.             //*lpData++ = rand()%256; // a random value [0..255]
  516.             *lpData++ = ch++;
  517.         }
  518.     
  519.         GetClientRect (hwnd, &rc); // Get the size of the window on the screen
  520.         // And slam the image onto the screen:
  521. #if defined (WIN32)
  522.         BitBlt(hdc, 0, 0, rc.right-rc.left, rc.bottom-rc.top, hdcImage, 0, 0, SRCCOPY);
  523. #else
  524.         WinGBitBlt(hdc, 0, 0, rc.right-rc.left, rc.bottom-rc.top, hdcImage, 0, 0);
  525. #endif
  526.     }
  527.     return TRUE;
  528. }
  529.  
  530.  
  531. /*----------------------------------------------------------------------------*\
  532. |   AppCommand(hwnd, msg, wParam, lParam )                                     |
  533. |                                                                              |
  534. |   Description:                                                               |
  535. |       handles WM_COMMAND messages for the main window (hwndApp)              |
  536. |       of the parent window's messages.                                       |
  537. |                                                                              |
  538. \*----------------------------------------------------------------------------*/
  539. LONG AppCommand (HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
  540. {
  541.     FARPROC fpAbout;
  542.     int idItem;
  543.     HWND hwndCtl;
  544.     WORD wNotifyCode;
  545.  
  546. #if defined(WIN32)
  547.     idItem = LOWORD(wParam);         // WIN32: control or menu item identifier
  548.     hwndCtl = (HWND)lParam;          // WIN32: handle of control
  549.     wNotifyCode = HIWORD(wParam);    // WIN32: notification message
  550. #else
  551.     idItem = wParam;                 // WIN16: control or menu item identifier
  552.     hwndCtl = (HWND) LOWORD(lParam); // WIN16: handle of control
  553.     wNotifyCode = HIWORD(lParam);    // WIN16: notification message
  554. #endif        
  555.     
  556.     switch(idItem) {
  557.         case MENU_ABOUT:
  558.             fpAbout = MakeProcInstance ((FARPROC)AppAbout, hInstApp);
  559.             DialogBox(hInstApp, szAppName, hwnd, (DLGPROC)fpAbout);
  560.             FreeProcInstance (fpAbout);
  561.             break;
  562.  
  563.         case MENU_EXIT:
  564.             PostMessage(hwnd,WM_CLOSE,0,0L);
  565.         break;
  566.     }
  567.     return 0L; // returning '0' means we processed this message.
  568. }
  569.  
  570.  
  571. /*----------------------------------------------------------------------------*\
  572. |   AppAbout( hDlg, uiMessage, wParam, lParam )                                |
  573. |                                                                              |
  574. |   Description:                                                               |
  575. |       This function handles messages belonging to the "About" dialog box.    |
  576. |       The only message that it looks for is WM_COMMAND, indicating the use   |
  577. |       has pressed the "OK" button.  When this happens, it takes down         |
  578. |       the dialog box.                                                        |
  579. |                                                                              |
  580. |   Arguments:                                                                 |
  581. |       hDlg            window handle of about dialog window                   |
  582. |       uiMessage       message number                                         |
  583. |       wParam          message-dependent                                      |
  584. |       lParam          message-dependent                                      |
  585. |                                                                              |
  586. |   Returns:                                                                   |
  587. |       TRUE if message has been processed, else FALSE                         |
  588. |                                                                              |
  589. \*----------------------------------------------------------------------------*/
  590. BOOL FAR PASCAL AppAbout(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
  591. {
  592.     int idItem;
  593.     HWND hwndCtl;
  594.     WORD wNotifyCode;
  595.     
  596.     switch (msg) {
  597.         case WM_INITDIALOG:
  598.             // Here is where you could move the dialog around, change
  599.             // some of the text that is going to be displayed, or other
  600.             // things that you want to have happen right before the 
  601.             // dialog is brought up.
  602.             return TRUE;
  603.         
  604.         case WM_COMMAND:
  605.             // A 'command' has been recieved by the dialog. Very few are
  606.             // actually possible in this dialog. Usually just the 'OK' button
  607. #if defined(WIN32)
  608.             idItem = LOWORD(wParam);         // WIN32: control or menu item identifier
  609.             hwndCtl = (HWND)lParam;          // WIN32: handle of control
  610.             wNotifyCode = HIWORD(wParam);    // WIN32: notification message
  611. #else
  612.             idItem = wParam;                 // WIN16: control or menu item identifier
  613.             hwndCtl = (HWND) LOWORD(lParam); // WIN16: handle of control
  614.             wNotifyCode = HIWORD(lParam);    // WIN16: notification message
  615. #endif        
  616.         if (idItem == IDOK) {
  617.                 EndDialog(hwnd,TRUE);
  618.         }
  619.         break;
  620.  
  621.     }
  622.     return FALSE;
  623. }
  624.  
  625.  
  626.  
  627. /*----------------------------------------------------------------------------*\
  628. |   AppExit()                                                                  |
  629. |                                                                              |
  630. |   Description:                                                               |
  631. |       app is just about to exit, cleanup                                     |
  632. |                                                                              |
  633. \*----------------------------------------------------------------------------*/
  634. void AppExit()
  635. {
  636.     // Clean up after ourselves...
  637.     
  638.     if (hdcImage) {
  639.         // Remove our Device Context that we got from WinG:
  640.         HBITMAP hbm;
  641.  
  642.         // Its not nice to delete a bitmap that is selected into a Device
  643.         // Context, so lets swap in the original bitmap, which will return
  644.         // to us our custom bitmap. You -did- remember to save the original
  645.         // bitmap didn't you?
  646.         hbm = (HBITMAP)SelectObject(hdcImage, gbmOldMonoBitmap);
  647.  
  648.         // Now we can delete the bitmap...
  649.         DeleteObject(hbm);
  650.  
  651.         // ...and the Device Context
  652.         DeleteDC(hdcImage);
  653.     }
  654.  
  655.     if(hpalApp) {
  656.         // And finally remove our Palette:
  657.         DeleteObject(hpalApp);
  658.     }
  659. }
  660.